本章節將深入探討兩種常見的卷類型:emptyDir
和 hostPath
。這兩者雖然概念簡單,但各自針對臨時緩存與持久化儲存提供了不同的解決方案,滿足了不同的應用場景需求。透過理解這兩種卷的特性與使用方法,將能更有效地設計、部署及管理 Kubernetes 應用。
emptyDir
是 Kubernetes 中的一種 Volume 類型。當一個 Pod 被指派到節點上運行時,emptyDir
Volume 會被創建,並在 Pod 的整個生命周期內存在。一旦該 Pod 被刪除,emptyDir
中的數據也會隨之消失。
emptyDir
提供了一個簡單的解決方案。以下是一個使用 emptyDir
的 Kubernetes 組態檔範例:
apiVersion: v1
kind: Pod
metadata:
name: emptydir-demo
spec:
containers:
- name: container1
image: busybox
command: [ "sh", "-c", "echo Hello from container1 > /data/message && sleep 3600" ]
volumeMounts:
- mountPath: /data
name: shared-data
- name: container2
image: busybox
command: [ "sh", "-c", "cat /data/message && sleep 3600" ]
volumeMounts:
- mountPath: /data
name: shared-data
volumes:
- name: shared-data
emptyDir: {}
apiVersion: v1
:指定使用的 Kubernetes API 版本為 v1。kind: Pod
:指定這個資源的類型是 Pod。metadata
:
name: emptydir-demo
:Pod 的名稱是 emptydir-demo
。spec
:
containers
:定義 Pod 內的容器。
name: container1
:第一個容器的名稱是 container1
。
image: busybox
:使用 busybox
這個 Docker 鏡像來啟動容器。
command
:容器啟動時執行的命令。這裡的命令是將訊息寫入 /data/message
,然後進入休眠。
volumeMounts
:將名為 shared-data
的卷掛載到容器內的 /data
路徑。
name: container2
:第二個容器的名稱是 container2
。
image: busybox
:使用 busybox
這個 Docker 鏡像來啟動容器。
command
:容器啟動時執行的命令。這裡的命令是讀取 /data/message
的內容,然後進入休眠。
volumeMounts
:將名為 shared-data
的卷掛載到容器內的 /data
路徑。
volumes
:定義 Pod 使用的卷。
name: shared-data
:卷的名稱是 shared-data
。emptyDir: {}
:使用 emptyDir
作為卷的類型,這是一個臨時目錄,可以在兩個容器之間共享數據。在這個範例中,我們定義了一個名為 emptydir-demo
的 Pod,該 Pod 包含兩個容器 container1
和 container2
。這兩個容器都掛載了一個名為 shared-data
的 emptyDir
Volume 到 /data
路徑。
container1
會在 /data/message
中寫入一個訊息。container2
則會從 /data/message
中讀取該訊息。這個設計允許這兩個容器共享數據,而 emptyDir
提供了一個簡單的機制來實現這一點。這個 emptyDir
Volume 是臨時的,當 Pod 被刪除時,所有數據都會消失。
組態檔案: emptyDir.yaml
apiVersion: v1
kind: Pod
metadata:
name: example-pod
spec:
containers:
- name: example-container
image: nginx
volumeMounts:
- name: emptydir-volume
mountPath: /usr/share/nginx/html
volumes:
- name: emptydir-volume
emptyDir: {} # 使用普通的 emptyDir
spec.containers[].volumeMounts
:容器的卷掛載配置。
name: emptydir-volume
:這個容器掛載的卷名稱是 emptydir-volume
。mountPath: /usr/share/nginx/html
:容器內的掛載點為 /usr/share/nginx/html
。spec.volumes
:定義這個 Pod 使用的卷。
name: emptydir-volume
:卷的名稱是 emptydir-volume
。emptyDir: {}
:使用普通的 emptyDir
作為卷的類型,表示一個臨時空目錄,當 Pod 被刪除時,這個目錄的數據將會消失。部署 Pod
kubectl apply -f emptyDir.yaml
kubectl exec -it example-pod -- /bin/sh
echo "Hello, emptyDir!" > /usr/share/nginx/html/testfile.txt
kubectl delete pod example-pod
kubectl apply -f emptyDir.yaml
kubectl exec -it example-pod -- /bin/sh
cat /usr/share/nginx/html/testfile.txt
---
cat: /usr/share/nginx/html/testfile.txt: No such file or directory
文件不存在,這表明 emptyDir
卷是臨時的,隨著 Pod 的刪除,數據也被刪除了。
在 Kubernetes 中,emptyDir
可以配置為使用節點的內存 (memory
) 來存儲數據,這樣可以提高 I/O 性能。
組態檔案: emptydir-memory.yaml
apiVersion: v1
kind: Pod
metadata:
name: example-pod
spec:
containers:
- name: example-container
image: nginx
volumeMounts:
- name: emptydir-memory
mountPath: /usr/share/nginx/html
volumes:
- name: emptydir-memory
emptyDir:
medium: Memory # 指定使用內存
kubectl apply -f emptydir-memory.yaml
kubectl exec -it example-pod -- /bin/sh
進入容器後,可以通過以下幾個方法檢查 emptyDir
是否使用了記憶體:
emptyDir
掛載點的文件系統類型df -h /usr/share/nginx/html
---
Filesystem Size Used Avail Use% Mounted on
tmpfs 32G 0 32G 0% /usr/share/nginx/html
如果掛載點顯示類型為 tmpfs
,那麼它使用的是內存。
kubectl top pod
---
NAME CPU(cores) MEMORY(bytes)
example-pod 0m 12Mi
dd if=/dev/zero of=/usr/share/nginx/html/testfile bs=1M count=100
kubectl top pod
---
NAME CPU(cores) MEMORY(bytes)
example-pod 2m 113Mi
內存使用量顯著增加,說明 emptyDir
正在使用內存。
hostPath
是 Kubernetes 中的一種 Volume 類型,允許你將 Kubernetes 節點上的檔案或目錄掛載到 Pod 中的容器內。當你使用 hostPath
時,你可以指定節點上的一個具體路徑,Pod 啟動後,該路徑會被掛載到容器內的指定路徑中。
hostPath
的主要用途是允許容器直接訪問 Kubernetes 節點上的文件系統資源。這在一些情況下非常有用,例如:
hostPath
來存取和分析節點上的日誌檔案。hostPath
來確保數據在 Pod 重啟後仍然存在。hostPath
可能使容器獲得過高的權限,增加安全風險。應在必要情況下使用,並考慮其他更安全的存儲選項。hostPath
所掛載的目錄或文件僅存在於 Kubernetes 集群中的某個特定節點上,而不是在整個集群中的所有節點上共享。因此,如果 Pod 因某種原因(例如節點故障、負載均衡)被重新調度到另一個節點,原來的 hostPath
路徑將不再可用,因為這個路徑不存在於新節點上。以下是一個使用 hostPath
的 Kubernetes 組態檔範例:
apiVersion: v1
kind: Pod
metadata:
name: hostpath-demo
spec:
containers:
- name: container1
image: busybox
command: [ "sh", "-c", "ls /mnt/hostpath && sleep 3600" ]
volumeMounts:
- mountPath: /mnt/hostpath
name: my-hostpath
volumes:
- name: my-hostpath
hostPath:
path: /data
type: Directory
apiVersion: v1
:指定使用的 Kubernetes API 版本為 v1。kind: Pod
:指定這個資源的類型是 Pod。metadata
:
name: hostpath-demo
:Pod 的名稱是 hostpath-demo
。spec
:
containers
:定義 Pod 內的容器。
name: container1
:容器的名稱是 container1
。image: busybox
:使用 busybox
這個 Docker 鏡像來啟動容器。command
:容器啟動時執行的命令,這裡是列出 /mnt/hostpath
目錄的內容,然後進入休眠。volumeMounts
:將名為 my-hostpath
的卷掛載到容器內的 /mnt/hostpath
路徑。volumes
:定義 Pod 使用的卷。
name: my-hostpath
:卷的名稱是 my-hostpath
。hostPath
:指定卷的來源為主機路徑。
path: /data
:主機上的路徑為 /data
。type: Directory
:指定該路徑的類型為目錄 (Directory)。在這個範例中,我們定義了一個名為 hostpath-demo
的 Pod,該 Pod 包含一個容器 container1
。我們使用 hostPath
Volume 將節點上的 /data
目錄掛載到容器內的 /mnt/hostpath
路徑中。
path
:指定主機上的目錄或檔案路徑。這個範例中為 /data
。type
:指定 hostPath
的類型,如 Directory
(目錄)、File
(檔案)等。這個範例中使用 Directory
。這個設計允許容器存取和使用節點上的本地資源,這在需要直接操作主機文件系統的情況下特別有用。
組態檔案: hostPath.yaml
apiVersion: v1
kind: Pod
metadata:
name: example-pod
spec:
nodeName: wslkind-worker2 # 調度 Pod 到特定的節點
containers:
- name: example-container
image: nginx
volumeMounts:
- name: hostpath-volume
mountPath: /usr/share/nginx/html # 容器內的掛載點
volumes:
- name: hostpath-volume
hostPath:
path: /data # 節點上的路徑
type: DirectoryOrCreate # 如果目錄不存在,則自動創建
kubectl apply -f hostPath.yaml
kubectl exec -it example-pod -- /bin/sh
echo "Hello, hostPath!" > /usr/share/nginx/html/testfile.txt
kubectl delete pod example-pod
kubectl apply -f hostPath.yaml
kubectl exec -it example-pod -- /bin/sh
cat /usr/share/nginx/html/testfile.txt
---
Hell: not found!
文件存在,這表明 hostPath
卷是持久儲存,儘管刪除了掛載的 Pod,數據依然存留。
emptyDir
和 hostPath
各有其獨特的特性和適用場景。在選擇使用哪種卷時,應根據應用的需求、數據持久化要求以及安全性考量來做出決策。
emptyDir
主要用於臨時緩存、數據處理中間存儲和多容器數據共享,它提供了一個簡單的機制來共享臨時數據。
hostPath
允許容器直接存取節點上的文件系統資源,這在一些需要存取特定系統文件或日誌文件、數據共享以及持久性數據存儲的場景下非常有用。然而,hostPath 也可能帶來安全風險,需要謹慎使用。